"""
安全上下文模块

提供一个基于 contextvars 的机制来在请求的生命周期内持有和访问 Principal 对象。
这使得在应用的任何层（例如服务层、数据访问层）都能够获取到当前登录的用户信息，
而无需在每个函数调用中显式传递 user_id 或 principal 对象。
"""
from contextvars import ContextVar
from typing import Optional

from axiom_boot.auth.models import Principal

# 创建一个上下文变量，它将在每个异步任务（例如 FastAPI 的每个请求）中拥有独立的值。
# default=None 确保在没有设置 principal 的上下文中（例如，在请求之外的后台任务中），
# 调用 .get() 将返回 None，而不是引发错误。
_principal_context: ContextVar[Optional[Principal]] = ContextVar("principal_context", default=None)


def set_current_principal(principal: Optional[Principal]):
    """
    为当前的上下文设置 Principal 对象。

    这应该由认证中间件在请求开始时调用。
    """
    _principal_context.set(principal)


def get_principal_context() -> Optional[Principal]:
    """
    获取当前上下文中的 Principal 对象。

    这可以在应用程序的任何地方调用，以获取与当前请求关联的用户信息。
    如果当前上下文没有 Principal（例如，对于匿名请求或在请求生命周期之外），
    则返回 None。

    用法:
        principal = get_principal_context()
        if principal:
            user_id = principal.user_info.id
            # ... a series of operations
    """
    return _principal_context.get()


def clear_principal_context():
    """
    清除当前上下文的 Principal。

    这应该由认证中间件在请求结束时调用，以进行垃圾回收并避免上下文泄漏。
    """
    _principal_context.set(None) 